// store.js
import { writable } from 'svelte/store';
import type { IndicatorGroupKey, IpcResponse, Kline, KlineFlat, Klt, Security, TradeBot, TrendLineResult } from './bindings';
import type { Table as FudaTable } from './bindings/Table'
import * as commands from '$lib/commands'
import { KLINE_INIT_SIZE, LimitedQueue } from '$lib';

export const klineResultStore = writable({
    // klt指定的kline总数
    klines: [] as KlineFlat[], // 使用 KlineFlat 类型注解 klines 数组,
});



export const klineRequestStore = writable({
    // security_id: '000001.SZ' as SecurityId,
    security_id: 'SZ.KZZ.128136',
    // klines of klt to retrieve 
    klt: 'DAY' as Klt,
    // request klines page num 
    page_num: 0,
    // request klines page size 
    page_size: KLINE_INIT_SIZE, // 初始化获取kline的记录数相当于2/3年的K线

});

export const klineTableConfStore = writable({

    klineTableConf: undefined as unknown as FudaTable | null,

});

const limitedQueue = new LimitedQueue<IndicatorGroupKey>(4);
limitedQueue.enqueue(['ADX', 'SAR', 'BOLL', 'MACD'])

export const indicatorYaxisStore = writable({
    yaxisQueue: limitedQueue,
});

// 经过测试，趋势线只需保存四个点（其实两个点即可，但是其中两个端点只是为了方便画线穿越整个canvas，其中两个点是人工选择的点为了显著绘制出趋势线），所以用一个数组即可
export const trend_line1: Kline[] = [
    {
        close: 272.6977619047619,
        high: 162.42,
        klt: "DAY",
        klts: "2024-04-26T00:00:00Z",
        low: 146.004,
        open: 147.25,
        volume: BigInt(509955),
        id: null,
        abuy_volume: null,
        asell_volume: null,
        idc_score: null,
        adx: null,
        aroon: null,
        aso: null,
        boll: null,
        cci: null,
        cko: null,
        cks: null,
        cmf: null,
        cmo: null,
        cpc: null,
        dcc: null,
        dpo: null,
        efi: null,
        eom: null,
        evl: null,
        ftf: null,
        hma: null,
        ikc: null,
        kama: null,
        kdj: null,
        knc: null,
        kst: null,
        kvo: null,
        lsma: null,
        sma: null,
        ema: null,
        macd: null,
        mfi: null,
        mti: null,
        pcs: null,
        prs: null,
        rsi: null,
        rvi: null,
        sar: null,
        sei: null,
        tdsi: null,
        trix: null,
        trsi: null,
        trend_lines: null,
        last_updated: null
    }, {
        close: 211.766,
        high: 213.888,
        klt: "DAY",
        klts: "2024-03-14T00:00:00Z",
        low: 198.968,
        open: 201.202,
        volume: BigInt(435098),
        id: null,
        abuy_volume: null,
        asell_volume: null,
        idc_score: null,
        adx: null,
        aroon: null,
        aso: null,
        boll: null,
        cci: null,
        cko: null,
        cks: null,
        cmf: null,
        cmo: null,
        cpc: null,
        dcc: null,
        dpo: null,
        efi: null,
        eom: null,
        evl: null,
        ftf: null,
        hma: null,
        ikc: null,
        kama: null,
        kdj: null,
        knc: null,
        kst: null,
        kvo: null,
        lsma: null,
        sma: null,
        ema: null,
        macd: null,
        mfi: null,
        mti: null,
        pcs: null,
        prs: null,
        rsi: null,
        rvi: null,
        sar: null,
        sei: null,
        tdsi: null,
        trix: null,
        trsi: null,
        trend_lines: null,
        last_updated: null
    }, {
        close: 167.643,
        high: 170.874,
        klt: "DAY",
        klts: "2024-02-06T00:00:00Z",
        low: 158.334,
        open: 164.017,
        volume: BigInt(68433),
        id: null,
        abuy_volume: null,
        asell_volume: null,
        idc_score: null,
        adx: null,
        aroon: null,
        aso: null,
        boll: null,
        cci: null,
        cko: null,
        cks: null,
        cmf: null,
        cmo: null,
        cpc: null,
        dcc: null,
        dpo: null,
        efi: null,
        eom: null,
        evl: null,
        ftf: null,
        hma: null,
        ikc: null,
        kama: null,
        kdj: null,
        knc: null,
        kst: null,
        kvo: null,
        lsma: null,
        sma: null,
        ema: null,
        macd: null,
        mfi: null,
        mti: null,
        pcs: null,
        prs: null,
        rsi: null,
        rvi: null,
        sar: null,
        sei: null,
        tdsi: null,
        trix: null,
        trsi: null,
        trend_lines: null,
        last_updated: null
    }, {
        close: -78.18514285714281,
        high: 195.998,
        klt: "DAY",
        klts: "2023-08-16T00:00:00Z",
        low: 193.8,
        open: 195.98,
        volume: BigInt(5161),
        id: null,
        abuy_volume: null,
        asell_volume: null,
        idc_score: null,
        adx: null,
        aroon: null,
        aso: null,
        boll: null,
        cci: null,
        cko: null,
        cks: null,
        cmf: null,
        cmo: null,
        cpc: null,
        dcc: null,
        dpo: null,
        efi: null,
        eom: null,
        evl: null,
        ftf: null,
        hma: null,
        ikc: null,
        kama: null,
        kdj: null,
        knc: null,
        kst: null,
        kvo: null,
        lsma: null,
        sma: null,
        ema: null,
        macd: null,
        mfi: null,
        mti: null,
        pcs: null,
        prs: null,
        rsi: null,
        rvi: null,
        sar: null,
        sei: null,
        tdsi: null,
        trix: null,
        trsi: null,
        trend_lines: null,
        last_updated: null
    }
];

export const trendLineStore = writable({
    // 趋势线
    lines: [
    ] as Kline[][],

    // Mouse Over Price[50]: x:1707177600000 2024/2/6 y:167.643
    // Mouse Over Price[29]: x:1710374400000 2024/3/14 y:211.766
    // Mouse Over Price[78]: x:1703635200000 2023/12/27 y:252.853


    // Mouse Over Price[50]:   y:167.643
    // Mouse Over Price[29]:   y:211.766
    // Mouse Over Price[78]:   y:252.853
});

// 用于控制初始化的全局标志
let isInitialized = false;

// 初始化函数
export async function initializeKlineTableConfStore() {
    if (isInitialized) return; // 避免重复初始化
    isInitialized = true;

    try {
        const res = await commands.get_kline_flat_table();
        if (res.error) {
            throw new Error(`Server returned an error: ${res.error}`);
        }
        klineTableConfStore.update(state => ({
            ...state,
            klineTableConf: res.result?.data ?? null,
        }));
    } catch (error) {
        console.error('(KlineTable.initializeKlineStore) Error fetching data:', error);
    }
}


export function setIndicatorChartYaxises(yaxises: IndicatorGroupKey[],) {

    indicatorYaxisStore.update(state => {
        // Create a new queue instance with the enqueued items, preserving the limit
        state.yaxisQueue.enqueue(yaxises);
        return { ...state }
    });
}

export function unsetIndicatorChartYaxises(yaxises: IndicatorGroupKey[],) {

    indicatorYaxisStore.update(state => {
        // Create a new queue instance with the enqueued items, preserving the limit
        state.yaxisQueue.dequeue(yaxises);
        return { ...state }
    });
}

export function updateKlineRequest(security_id: string | null, klt: Klt | null, page_num: number | null, page_size: number | null) {

    console.log(`(updateKlineRequest) security_id: ${security_id} klt: ${klt}, page_num: ${page_num} page_size: ${page_size}`)

    if (security_id) {
        klineRequestStore.update(state => ({ ...state, security_id: security_id }));
    }
    if (klt) {
        klineRequestStore.update(state => ({ ...state, klt: klt }));
    }

    if (page_num) {
        klineRequestStore.update(state => ({ ...state, page_num: page_num }));
    }

    if (page_size) {
        klineRequestStore.update(state => ({ ...state, page_size: page_size }));
    }
}



export const historyStore = writable({
    current_tbot: null as unknown as TradeBot,
    current_security: null as unknown as Security,
});

export function updateHistoryStore(tbot: TradeBot | null, security: Security | null) {

    console.log("updateHistoryStore tbot= ", tbot, " security= ", security);
    if (tbot) {
        historyStore.update(state => ({ ...state, current_tbot: tbot }));
    }


    if (security) {
        historyStore.update(state => ({ ...state, current_security: security }));
    }

}
